from django.shortcuts import render
# Create your views here.
from django.views import View
from django.http import JsonResponse
from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings
from .models import OAuthQQUser
from users.models import User
from django.contrib.auth import login
from itsdangerous import TimedJSONWebSignatureSerializer
import json, re
from django_redis import get_redis_connection


def generate_access_token(openid):
    serializer = TimedJSONWebSignatureSerializer(
        secret_key=settings.SECRET_KEY,
        expires_in=3600
    )
    data = {'openid': openid}
    access_token = serializer.dumps(data)
    return access_token.decode()


def check_access_token(token):
    serializer = TimedJSONWebSignatureSerializer(
        secret_key=settings.SECRET_KEY
    )
    data = serializer.loads(token)
    openid = data.get('openid')
    return openid


class QQFirstView(View):
    def get(self, request):
        next_url = request.GET.get('next')
        oauth_qq = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,
            state=next_url
        )
        login_url = oauth_qq.get_qq_url()
        return JsonResponse({
            'code': 0,
            'errmsg': 'OK',
            'login_url': login_url
        })


class QQUserView(View):
    def get(self, request):
        code = request.GET.get('code')
        try:
            oauth_qq = OAuthQQ(
                client_id=settings.QQ_CLIENT_ID,
                client_secret=settings.QQ_CLIENT_SECRET,
                redirect_uri=settings.QQ_REDIRECT_URI
            )
            token = oauth_qq.get_access_token(code)
            openid = oauth_qq.get_open_id(access_token=token)
        except Exception as e:
            print(e)
            return JsonResponse({
                'code': 400,
                'errmsg': 'qq登录失败'
            })
        try:
            oauth_qq = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist as e:
            access_token = generate_access_token(openid)
            return JsonResponse({
                'access_token': access_token
            })
        user = oauth_qq.user
        login(request, user)
        response = JsonResponse({'code': 0, 'errmsg': 'OK'})
        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)
        return response

    def post(self, request):
        data = json.loads(request.body.decode())
        mobile = data.get('mobile')
        password = data.get('password')
        sms_code = data.get('sms_code')
        access_token = data.get('access_token')

        if not all([mobile, password, sms_code, access_token]):
            return JsonResponse({'code': 400, 'errmsg': '缺少参数'})
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400, 'errmsg': '手机号输入错误'})
        if not re.match(r'^\w{8,20}$', password):
            return JsonResponse({'code': 400, 'errmsg': '密码输入错误'})
        conn = get_redis_connection('sms_code')
        sms_code_from_redis = conn.get('sms_%s' % mobile)
        if not sms_code_from_redis:
            return JsonResponse({'code': 400, 'errmsg': '验证码已失效'})
        if sms_code_from_redis.decode() != sms_code:
            return JsonResponse({'code': 400, 'errmsg': '验证码输入错误'})
        openid = check_access_token(access_token)
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist as e:
            print(e)
            user = User.objects.create_user(
                username=mobile,
                password=password,
                mobile=mobile
            )
        else:
            if not user.check_password(password):
                return ({'code': 400, 'errmsg': '输入的密码不正确'})
        try:
            OAuthQQUser.objects.create(openid=openid, user=user)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '添加数据错误'})
        login(request, user)
        response = JsonResponse({'code': 0, 'errmsg': 'OK'})
        return response
